Одной из широко
известных структур данных для представления множеств является двоичное дерево
поиска. Каждый узел v такого дерева
содержит один элемент множества, при этом все элементы в левом поддереве v должны быть меньше элемента в v, а элементы в правом поддереве v должны быть больше элемента в v. Пример двоичного дерева поиска
показан на рисунке. Узел называется корнем, если у него нет родителя (узел 5 на
рисунке). Узел называется листом, если у него нет детей (узлы 2, 4 и 8 на
рисунке). Путём в дереве назовём последовательность номеров узлов, таких что
каждый следующий узел является непосредственным потомком предыдущего.
Вам дана
последовательность неповторяющихся целых чисел. Требуется определить,
существует ли такое двоичное дерево поиска, в котором эта последовательность
является путём от корня к какому-то листу. Например, дерево поиска с путём
5-1-3-2 существует, а с путём 5-2-3-1 нет.
Вход. Задано последовательность чисел, разделённых пробелами
и/или переводами строк. До первого и после последнего числа могут быть пробелы
и переводы строк. Все числа различны. Количество чисел от 1 до 50 000. Значения
чисел от -2 147 483 648 до 2 147 483 647 включительно.
Выход. Выведите слово
"YES", если дерево, соответствующее заданному пути, существует, и
"NO" в противном случае.
Пример
входа |
Пример
выхода |
5 1 3 2 |
YES |
структуры
данных - дерево
Изначально
считаем, что все входное множество чисел лежит в промежутке [min; max]
= [-2 147 483 648; 2 147 483 647]. Рассмотрим два последовательных числа
входной последовательности: prev и cur. Если cur > prev, то далее
числа должны лежать в интервале [prev;
max]. Иначе следующие числа должны
принадлежать интервалу [min; prev].
Если на какой-то
итерации значение cur не принадлежит
текущему интервалу [min; max], то такого пути в дереве не
существует.
Объявим границы
[min; max] входных чисел.
max = 2147483647; min = max + 1;
Читаем
числа prev и cur.
scanf("%d",&prev);
while(scanf("%d",&cur)
== 1)
{
Если значение cur не принадлежит интервалу [min;
max], то искомого пути в дереве не
существует.
if ((cur < min) || (cur > max))
{
puts("NO");
return 0;
}
Изменяем
границы интервала [min; max].
if (cur > prev) min = prev; else max = prev;
prev = cur;
}
Если все
числа обработаны корректно, то искомый путь в дереве существует.
puts("YES");